#!/bin/sh

extract()
{
  filenums=`echo $cmds | awk -v idx=$1 '{
    split($0, a, " ");
    list = "";
    for(v in a) {
      if(v > idx) {
        if(a[v] ~ /[0-9]/ || a[v] ~ "-" || a[v] ~ ",") {
          list = list a[v];
        }
      }
    }
    split(list, arr, ",");
    final="";
    for(i in arr) {
      if(arr[i] ~ "-") {
        split(arr[i], inner, "-");
        for(k = inner[1]; k <= inner[2]; k++) {
          final=final "," k;
        }
      } else {
        final=final "," arr[i]
      }
    }
    printf("%s", substr(final, 2));
  }'`
}

removetemp()
{
  filepaths=`git status | awk '
    $0 ~ ".gt-temp1.txt" || $0 ~ ".gt-temp.txt" {
      printf("%s ", $1);
    }
  '`

  if test "$filepaths" != ""; then
    rm $filepaths
  fi
}

status()
{
  cmd=`git status 2>&1 | tee /tmp/.gt-temp.txt`
  awk '
    BEGIN {
      num = 0;
    }
    $0 ~ "Untracked" {
      untracked = 1
      committed = 0;
      notcommitted = 0;
      first = 1;
    }
    $0 ~ "Changes not" {
      untracked = 0;
      committed = 0;
      notcommitted = 1;
      first = 1;
    }
    $0 ~ "Changes to" {
      untracked = 0;
      committed = 1;
      notcommitted = 0;
      first = 1;
    }
    {
      if($0 ~ "use \"git " || first) {
        printf("\033[38m%s\033[0m\n", $0);
        first = 0;
      } else if($0 ~ ".gt-temp") {

      } else if(committed && $0 ~ /[^\s\\]/) {
        num++;
        printf("\033[1m%d\033[0m.\033[32m%s\033[0m\n", num, $0)
      } else if((untracked || notcommitted) && $0 ~ /[^\s\\]/) {
        num++;
        printf("\033[1m%d\033[0m.\033[31m%s\033[0m\n", num, $0)
      } else
        printf("\033[38m%s\033[0m\n", $0)
    }' /tmp/.gt-temp.txt > /tmp/.gt-temp1.txt
  if test $1 = 1; then
    cat /tmp/.gt-temp1.txt
    rm /tmp/.gt-temp1.txt
  else
    awk '{ gsub("\x1B[(([0-9]{1,2})?(;)?([0-9]{1,2})?)?[m,K,H,f,J]", ""); print $0 }' /tmp/.gt-temp1.txt > /tmp/.gt-temp2.txt
    cat /tmp/.gt-temp2.txt > /tmp/.gt-temp1.txt
    rm /tmp/.gt-temp2.txt
  fi
}

# TODO: work with file names and paths
make_file_list()
{
  files=`awk -v t=$1 -v arg=$2 '
      BEGIN {
        split(arg, nums, ",");
        ff = 0;
      }
      {
        if($0 ~ "--staged" && ff == 0 && t == "restore") {
          printf("--staged ");
        }
        if($1 ~ /[\.]/) {
          for(i in nums) {
            withp = nums[i]"."
            if(withp == $1) {
              printf("%s ", $NF);
              ff++;
            }
          }
        }
      }
    ' /tmp/.gt-temp1.txt`
}

if test "$1" = ""; then
  status 1
  removetemp
  exit 1
fi

cmds=`echo $1 | sed  's/\(.\)/\1 /g'`
shift

IN_STASH=0
i=0
echo "$cmds" | tr ' ' '\n' | while read c;
do
i=${i+1}
case $c in
  a)
    next=`echo $cmds | cut -d\  -f${i+2}`
    if test "$next" = "."; then
      removetemp
      git add .
    elif test "$next" = "a"; then
      git add $@
    else
      status 0
      extract $i
      make_file_list "add" $filenums
      git add $files
      removetemp
    fi
    ;;
  s)
    if test $IN_STASH = 1; then
      git stash show $@
    else
      status 1
    fi
    ;;
  S)
    next=`echo $cmds | cut -d\  -f${i+2}`
    if test $IN_STASH = 1; then
      git stash save $@
    elif test "$next" = "S"; then
      git stash
    else
      IN_STASH=1
    fi
    ;;
  p)
    if test $IN_STASH = 1; then
      git stash pop $@
    else
      git pull
    fi
    ;;
  P)
    cmd=`git push 2>&1 | tee /tmp/.gt-temp.txt | awk '$0 ~ "git push --set-upstream" { print $0 }'`
    if test "$cmd" = ""; then
      cat /tmp/.gt-temp.txt
      rm /tmp/.gt-temp.txt
      exit 0
    else
      echo "Running: ${cmd}"
      removetemp
      eval $cmd
      exit 0
    fi
    ;;
  c)
    if test $IN_STASH = 1; then
      git stash clear $@
    else
      git commit
    fi
    ;;
  C)
    git checkout $1
    shift
    ;;
  l)
    if test $IN_STASH = 1; then
      git stash list $@
    else
      git log
    fi
    ;;
  M)
    git merge $1
    shift
    ;;
  b)
    if test $IN_STASH = 1; then
      git stash branch $@
    else
      git branch $1
      shift
    fi
    ;;
  d)
    if test $IN_STASH = 1; then
      git stash drop $@
    else
      git diff $1
    fi
    ;;
  r)
    status 0
    extract $i
    make_file_list "restore" $filenums
    git restore $files
    status 1
    ;;
  R)
    next=`echo $cmds | cut -d\  -f${i+2}`
    if test "$next" = ""; then
      removetemp
      git rm $@
    else
      status 0
      extract $i
      make_file_list "add" $filenums
      git rm $files
      removetemp
    fi
    ;;
  g)
    git grep -n "$1"
    ;;
  q)
    break
    ;;
  *)
   ;;
esac
done

exit 0
